package controller;

import common.*;
import common.Constants.MessageType;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutput;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.Arrays;

public class Message implements Serializable {

	private static final long serialVersionUID = 1L;
	private transient int source_id;
	private transient int destination_id;
	private Constants.MessageType message_type;
	private int ballotNum;
	private int acceptNum;
	private String acceptVal;

	public Message(int sourceId, int destinationId,
			Constants.MessageType message_type, int ballotNum, int acceptNum,
			String acceptVal) {
		this.source_id = sourceId;
		this.destination_id = destinationId;
		this.message_type = message_type;
		this.acceptNum = acceptNum;
		this.acceptVal = acceptVal;
		this.ballotNum = ballotNum;
	}

	public Message(byte[] byteStream) {

		this.source_id = byteStream[0];
		this.destination_id = byteStream[1];

		byte[] objectBytes = Arrays.copyOfRange(byteStream, 2,
				byteStream.length);

		ByteArrayInputStream bis = new ByteArrayInputStream(objectBytes);
		try {
			ObjectInputStream in = new ObjectInputStream(bis);
			try {
				Message nm = (Message) in.readObject();
				this.acceptNum = nm.getAcceptNum();
				this.acceptVal=nm.getAcceptValue();
				this.ballotNum=nm.getBallotNum();
				this.message_type=nm.getMessageType();				
				
				in.close();
			} catch (ClassNotFoundException e) {
				e.printStackTrace();
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	public MessageType getMessageType() {
		return this.message_type;
	}

	public String getAcceptValue() {
		return this.acceptVal;
	}

	public int getSourceId() {
		return source_id;
	}

	public int getDestinationId() {
		return destination_id;
	}

	public byte[] serialize() {
		byte[] serializedMessage = null;
		ByteArrayOutputStream bos = new ByteArrayOutputStream();

		try {
			ObjectOutput out = new ObjectOutputStream(bos);
			out.writeObject(this);
			out.close();

			serializedMessage = bos.toByteArray();
		} catch (IOException e) {
			e.printStackTrace();
		}

		byte sourceIdByte = new Integer(this.source_id).byteValue();
		byte destnIdByte = new Integer(this.destination_id).byteValue();

		byte[] msg = new byte[serializedMessage.length + 3];
		msg[0] = sourceIdByte;
		msg[1] = destnIdByte;

		for (int index = 0; index < serializedMessage.length; index++) {
			msg[index + 2] = serializedMessage[index];
		}

		return msg;
	}

	public String toString() {
		StringBuffer str = new StringBuffer();
		str.append("{");
		str.append("\n\t" + this.getSourceId() + " -> " + this.getDestinationId());
		str.append("\n\t"+"Message Type : "+this.getMessageType());
		str.append("\n\t" + "Ballot Number : "+this.getBallotNum());
		str.append("\n\t" + "Accept Value : "+this.getAcceptValue());
		str.append("\n\t" + "Accept Number : "+this.getAcceptNum());
		str.append("\n}");
		
		return str.toString();
	}

	public static void main(String args[]) {
	}

	public int getBallotNum() {
		return this.ballotNum;
	}
	
	public int getAcceptNum() {
		return this.acceptNum;
	}
}
